package com.apetrenko.avaya.callstore.server;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.apetrenko.avaya.callstore.client.Config;

public class ContextListener implements ServletContextListener {

	public static final String ATTR_ARCHIVER = "archiver";
	public static final String ATTR_CONFIG = "config";
	public static final String ATTR_DBADAPTER = "dbadapter";
	public static final String ATTR_TIMER = "timer";
	public static final String ATTR_CONFIG_STORAGE = "config_storage";

	@Override
	public void contextDestroyed(ServletContextEvent aSce) {
		ServletContext vServletContext = aSce.getServletContext();

		removeArchiverTask(vServletContext);
		closeArchiver(vServletContext);
		closeDbAdapter(vServletContext);

		vServletContext.removeAttribute(ATTR_CONFIG);
	}

	private void closeDbAdapter(ServletContext aServletContext) {
		DbAdapter vDbAdapter = (DbAdapter) aServletContext
				.getAttribute(ATTR_DBADAPTER);

		if (vDbAdapter != null) {
			vDbAdapter.close();
		}

		aServletContext.removeAttribute(ATTR_DBADAPTER);

	}

	private void closeArchiver(ServletContext aServletContext) {
		Archiver vArchiver = (Archiver) aServletContext
				.getAttribute(ATTR_ARCHIVER);

		if (vArchiver != null) {
			vArchiver.close();
		}

		aServletContext.removeAttribute(ATTR_ARCHIVER);
	}

	private void removeArchiverTask(ServletContext aServletContext) {
		Timer vTimer = (Timer) aServletContext.getAttribute(ATTR_TIMER);

		if (vTimer != null)
			vTimer.cancel();

		aServletContext.removeAttribute(ATTR_TIMER);
	}

	@Override
	public void contextInitialized(ServletContextEvent aSce) {
		ServletContext vServletContext = aSce.getServletContext();

		loadConfig(vServletContext);
		createDbAdapter(vServletContext);
		createArchiver(vServletContext);
		createArchiverTask(vServletContext);
	}

	private void createArchiverTask(ServletContext aServletContext) {
		try {
			Config vConfig = (Config) aServletContext.getAttribute(ATTR_CONFIG);
			Archiver vArchiver = (Archiver) aServletContext
					.getAttribute("archiver");
			Timer vTimer = new Timer();
			TimerTask vTask = new ArchiverTask(vArchiver);

			Calendar vCalendar = Calendar.getInstance();
			Date vStartTime = vCalendar.getTime();

			vTimer.scheduleAtFixedRate(vTask, vStartTime, vConfig
					.getArchivePeriod() * 1000);

			aServletContext.setAttribute(ATTR_TIMER, vTimer);
		} catch (Exception e) {

		}

	}

	private void createArchiver(ServletContext aServletContext) {
		Config vConfig = (Config) aServletContext.getAttribute(ATTR_CONFIG);
		Archiver vArchiver = new Archiver();
		vArchiver.init(vConfig);
		DbAdapter vDbAdapter = (DbAdapter) aServletContext
				.getAttribute(ATTR_DBADAPTER);
		vArchiver.setDbAdapter(vDbAdapter);
		aServletContext.setAttribute(ATTR_ARCHIVER, vArchiver);
	}

	private void createDbAdapter(ServletContext aServletContext) {
		Config vConfig = (Config) aServletContext.getAttribute(ATTR_CONFIG);
		DbAdapter vAdapter = new DbAdapter();
		vAdapter.init(vConfig);
		aServletContext.setAttribute(ATTR_DBADAPTER, vAdapter);
	}

	private void loadConfig(ServletContext aServletContext) {
		ConfigStorage vConfigStore = new ConfigStorage();
		vConfigStore.init(this.getClass());

		Config vConfig = vConfigStore.load();

		aServletContext.setAttribute(ATTR_CONFIG_STORAGE, vConfigStore);
		aServletContext.setAttribute(ATTR_CONFIG, vConfig);
	}

}
